//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 09/26/2016 11:10:45 AM
// Design Name: 
// Module Name: key_proc
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps 
module keypro(
    input             sys_clk_100m,
    input             sys_rstn,

    output wire       slow_clk30k_out,    
    output wire       slow_clk1k_out ,    
    
    input  wire       heat_touch   , 
    input  wire       hall_touch   ,
    input  wire       posl_touch   ,
    input  wire       posr_touch   , 
    input  wire       init_touch   , 
    input  wire       fusion_touch , 
    output reg [7:0]  touch_status ,    

    input      [10:0] key,
    output reg [10:0] keyout,
    output reg        key_intr
);
//--------------------------------------------------------
`ifdef SIMULATION
localparam PERIOD_CLK0 = 1000/2;
localparam PERIOD_CLK1 = 100/2;
localparam PERIOD_CLK2 = 33/2;
`else
localparam PERIOD_CLK0 = 100000/2;
localparam PERIOD_CLK1 = 10000/2;
localparam PERIOD_CLK2 = 3333/2;    
`endif
//--------------------------------------------------------
reg[31:0] counter_1k;
reg[31:0] counter_10k;
reg[31:0] counter_30k;
reg       clk30k_out; 
reg       clk10k_out;    
reg       clk1k_out;    
wire      rst = ~sys_rstn;
reg       intout_ff1;
reg       intout;

reg[15:0] counter;
reg[1:0]  state;
reg       clr;

wire      slow_clk10k_out;
wire[3:0] touch_detect = {hall_touch,posr_touch,posl_touch,init_touch};
//--------------------------------------------------------
always @(posedge slow_clk10k_out,posedge rst) begin
    if(rst)begin 
        touch_status <= 8'b0;    
    end 
    else begin 
        touch_status <= {2'b0,heat_touch,fusion_touch,hall_touch,posr_touch,posl_touch,init_touch};  
    end 
end 
//--------------------------------------------------------
always@(posedge sys_clk_100m,posedge rst) begin
    if (rst) begin
        counter_1k <= 0;
    end
    else begin
         counter_1k <= (counter_1k > PERIOD_CLK0*2 )? 0:(counter_1k + 1);
    end
end
//--------------------------------------------------------
always@(posedge sys_clk_100m,posedge rst) begin
    if (rst) begin
        counter_10k <= 0;
    end
    else begin
        counter_10k <= (counter_10k > PERIOD_CLK1*2 )?0:(counter_10k + 1);
    end
end
//--------------------------------------------------------
always@(posedge sys_clk_100m,posedge rst) begin
    if (rst) begin
        counter_30k <= 0;
    end
    else begin
         counter_30k <= (counter_30k > PERIOD_CLK2*2 )? 0:(counter_30k + 1);
    end
end
//--------------------------------------------------------
always@(posedge sys_clk_100m) clk1k_out  <= (counter_1k  > PERIOD_CLK0)?1'b1:1'b0;
always@(posedge sys_clk_100m) clk10k_out <= (counter_10k > PERIOD_CLK1)?1'b1:1'b0;
always@(posedge sys_clk_100m) clk30k_out <= (counter_30k > PERIOD_CLK2)?1'b1:1'b0;
//--------------------------------------------------------
reg[11:0]  keyin_ff1;
reg        key_press;
always @(posedge slow_clk10k_out) keyin_ff1 <= {1'b1,key};
always @(posedge slow_clk10k_out) key_press <= (keyin_ff1 == 12'hfff)?1'b0:1'b1;
//--------------------------------------------------------
always @(posedge slow_clk10k_out) begin
    case (state )
        2'b00: begin
            intout <= 0;
            clr    <= 0;
            state  <= (key_press)? 1:0;
        end
        2'b01: begin
            if (counter == 250) begin
                intout <= key_press ? 1'b1:1'b0;
                state  <= 2;
                clr    <= 0; 
            end
            else begin
                clr <= 1;
            end
        end
        2'b10: begin
            if (key_press) begin
                if (counter == 10000) begin
                    state  <= 3;
                    intout <= 1;
                    clr    <= 0;
                end
                else begin
                    clr    <= 1;
                    intout <= 0;
                end
            end
            else  begin
                state  <= 0;
                intout <= 0;
                clr    <= 0;
            end
        end
        2'b11: begin
           if (key_press)  begin
                if (counter == 1000) begin
                    intout <= 1;
                    clr    <= 0;
                end
                else  begin
                    clr    <= 1;
                    intout <= 0;
                end
           end
           else begin
                state  <= 0;
                intout <= 0;
                clr    <= 0;
            end
        end
        default: begin
            state  <= 0;
        end
    endcase
end
//--------------------------------------------------------
always @(posedge slow_clk10k_out ) counter    <= (clr == 0)?0:(counter +1);
//-------------------------------------------------------- 
always @(posedge slow_clk10k_out ) intout_ff1 <= intout;
always @(posedge slow_clk10k_out ) key_intr   <= intout_ff1;
//--------------------------------------------------------
always @(posedge slow_clk10k_out )  keyout     <= key;
//--------------------------------------------------------
BUFG inst0(
    .I(clk30k_out),
    .O(slow_clk30k_out)
);
//--------------------------------------------------------
BUFG inst1(
    .I(clk10k_out),
    .O(slow_clk10k_out)
);
//--------------------------------------------------------
BUFG inst2(
    .I(clk1k_out),
    .O(slow_clk1k_out)
);
//--------------------------------------------------------

endmodule
